package interpreter

import (
	"bytes"
	"strconv"
	"strings"
)
type ReaderCreateFunc func(head []byte,body[]byte)(Reader,error)

const (
	Body="body"
	Header="header"
	Restful="restful"
	Query = "query"
	Cookie="cookie"
)

var(
	creators map[string]ReaderCreateFunc
	readers map[string][]byte
	pathSplitSeq = []byte(".")
)
func init() {
	creators = make(map[string]ReaderCreateFunc)
	readers = make(map[string][]byte)

	readers[Body[:4]]=[]byte(Body)
	readers[Header[:4]]=[]byte(Header)
	readers[Restful[:4]]=[]byte(Restful)
	readers[Cookie[:4]]=[]byte(Cookie)
	readers[Query[:4]]=[]byte(Query)

	creators[Body] = ReaderCreateFunc(func(head []byte,body[]byte)(Reader,error) {

		index := 0
		if len(head)>len(Body){
			indexData := head[len(Body):]
			i,err:= strconv.Atoi(string(indexData))
			if err!= nil{
				return nil,err
			}
			index = i
		}

		pathData:= bytes.Split(body,pathSplitSeq)

		path:=make([]string,0,len(pathData))
		for _,p:=range pathData{
			path= append(path,string(p))
		}


		return &_BodyReader{
			Index: index,
			Path:  path,
			Name:string(body),
		}, nil
	})
	creators[Header] = ReaderCreateFunc(func(head []byte,body[]byte)(Reader,error) {
		index := 0
		if len(head)>len(Header){
			indexData := head[len(Header):]
			i,err:= strconv.Atoi(string(indexData))
			if err!= nil{
				return nil,err
			}
			index = i
		}

		return &_HeaderReader{
			Index: index,
			Key:   string(body),
		}, nil
	})
	creators[Query] = ReaderCreateFunc(func(head []byte,body[]byte)(Reader,error) {
		if !bytes.Equal(head,[]byte(Query)){
			return nil,GrammarError(string(head))
		}
		return &_QueryReader{
			Key: string(body),
		},nil
	})
	creators[Restful] = ReaderCreateFunc(genResfult)
	creators[Cookie] = ReaderCreateFunc(func(head []byte,body[]byte)(Reader,error) {
		index := 0
		if len(head)>len(Cookie){
			indexData := head[len(Cookie):]
			i,err:= strconv.Atoi(string(indexData))
			if err!= nil{
				return nil,err
			}
			index = i
		}

		return &_CookieReader{
			Index: index,
			Name:  string(body),
		}, nil
	})
}

func genResfult(head[]byte,body[]byte)(Reader,error) {

	if !bytes.Equal(head,[]byte(Restful)){
		return nil,GrammarError(string(head))
	}
	return &_RestFulReader{
		Key: string(body),
	},nil
}

func genReader(line []byte)(Reader ,error) {

	kindex:=bytes.IndexAny(line,".")

	if kindex == -1{
		return nil, GrammarError(line)
	}

	key:= line[:kindex]
	keyPre:=strings.ToLower(string(key[:4]))

	cmd,has:=readers[keyPre]
	if !has{
		return nil,GrammarError(string(line))
	}
	if !bytes.HasPrefix(key,cmd){
		return nil,GrammarError(string(line))
	}

	create:= creators[string(cmd)]

	return create(bytes.ToLower(key),line[kindex+1:])

}


